#include "flip_internal.hpp"

#include <gvl/io/fstream.hpp>
#include <flip/loader/png_loader.hpp>

using namespace Flip;

int flip_image_tag;
int flip_sprite_tag;

LUAF(create_image)
{
	int width = luaL_checkint(L, 1);
	int height = luaL_checkint(L, 2);

	void* mem = lua_newuserdata(L, sizeof(Image));
	Image* self = new (mem) Image(width, height, Flip::pf_8888);
	prepare_object(L, &flip_image_tag); // self -- self

	return 1;
}

LUAF(load_image)
{
	char const* path = luaL_checkstring(L, 1);

	void* mem = lua_newuserdata(L, sizeof(Image));
	/*
	Image* self = new (mem) Image(
		Flip::loadPngImageData<ImageData>(gvl::stream_ptr(new gvl::fstream(path, "rb"))));*/
	Image* self = new (mem) Image(
		Flip::loadPng(gvl::stream_ptr(new gvl::fstream(path, "rb"))));
	prepare_object(L, &flip_image_tag); // self -- self
		
	return 1;
}

LUAF(setpixel)
{
	auto& image = check_image(L, 1);

	int x = luaL_checkint(L, 2);
	int y = luaL_checkint(L, 3);
	uint32_t r = luaL_checkint(L, 4);
	uint32_t g = luaL_checkint(L, 5);
	uint32_t b = luaL_checkint(L, 6);
	uint32_t a = luaL_optint(L, 7, 255);
	
	image.setPixel(x, y, image.pixel(r, g, b, a));
	return 0;
}

LUAF(image_dim)
{
	auto& image = check_image(L, 1);

	lua_pushinteger(L, image.width);
	lua_pushinteger(L, image.height);
	return 2;
}

LUAF(to_sprite)
{
	auto& image = check_image(L, 1);

	void* mem = lua_newuserdata(L, sizeof(RenderableImage));
	RenderableImage* self = new (mem) RenderableImage(image.data());
	prepare_object(L, &flip_sprite_tag); // self -- self
	self->bevel(RenderableImage::Repeat);

	return 1;
}

#if 0
LUAF(upload_sprite)
{
	auto& sprite = check_sprite(L, 1);

	sprite.upload();

	RenderableImageData& data = *sprite.data();

	lua_pushinteger(L, data.textureData->id);
	lua_pushnumber(L, data.tx1);
	lua_pushnumber(L, data.ty1);
	lua_pushnumber(L, data.tx2);
	lua_pushnumber(L, data.ty2);
	lua_pushnumber(L, data.tx3);
	lua_pushnumber(L, data.ty3);
	lua_pushnumber(L, data.tx4);
	lua_pushnumber(L, data.ty4);

	return 9;
}
#endif

LUAF(image_gc)
{
	auto& image = check_image(L, 1);

	luaext_setuserdatatag(L, 1, 0);
	image.~Image();
	
	return 0;
}

LUAF(sprite_gc)
{
	auto& sprite = check_sprite(L, 1);

	luaext_setuserdatatag(L, 1, 0);
	sprite.~RenderableImage();
	
	return 0;
}